package api

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"sync"
)

// Messages 信息 结构体
type Messages struct {
	//登录的用户ID
	UserId int
	//接受信息的用户ID
	SendId int
}

// Nodes Websocket 结构体
type Nodes struct {
	Total *websocket.Conn
	Data  chan []byte
}

// 创建一个 客户端
var clientMap map[int]*Nodes = make(map[int]*Nodes, 0)

// 使用等待组
var w sync.WaitGroup
var s sync.Mutex

// Chat 结构体控制下的 函数
func Chat(ctx *gin.Context) {
	userId := ctx.GetInt("user_id")
	sendId := ctx.GetInt("send_id")
	coon, err := (&websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		//升级协议
	}).Upgrade(ctx.Writer, ctx.Request, nil)
	if err != nil {
		log.Println(err.Error())
	}
	//实例化一个 结构体
	n := &Nodes{
		Total: coon,
		Data:  make(chan []byte, 50),
	}
	//映射一个用户关系 给谁发信息
	clientMap[userId] = n
	//实例化这个结构体
	m := &Messages{
		UserId: userId,
		SendId: sendId,
	}
	//创建一个等待组
	w.Add(2)
	//开启一个 发送信息的携程
	go sendMassage(n)
	//开启一个接受信息的携程
	go acceptMessage(n, m)
	w.Wait()
}

// 发送信息
func sendMassage(n *Nodes) {
	defer w.Done()
	for {
		select {
		//从管道中读取数据
		case data := <-n.Data:
			//写入 websocket
			err := n.Total.WriteMessage(websocket.TextMessage, data)
			if err != nil {
				fmt.Println("消息发送失败", err)
				return
			}
		}
	}
}

// 接受信息
func acceptMessage(n *Nodes, m *Messages) {
	defer w.Done()
	for {
		//读取数据
		_, msg, err := n.Total.ReadMessage()
		if err != nil {
			//打印错误
			fmt.Println("Error reading message" + err.Error())
		}
		//设置要发给谁
		node, ok := clientMap[m.SendId]
		if ok {
			//向管道中写数据
			node.Data <- msg
		}
	}
}
